package com.easyj.admin.edu.serviceimpl;

import java.util.List;
import java.util.Date;
import java.util.HashMap;

import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.easyj.admin.edu.service.PublishService;
import com.easyj.admin.activiti.service.TaskCommentService;
import com.easyj.admin.activiti.utils.ProcessUtils;
import com.easyj.admin.activiti.vo.SimpleApproveVO;
import com.easyj.admin.db.mapper.PublishMapper;
import com.easyj.base.exception.*;
import com.easyj.base.security.SimpleUser;
import com.easyj.base.security.service.SecurityUtil;
import com.easyj.base.enums.Level2ApplyStatusEnum;
import com.easyj.base.common.page.Page;
import com.easyj.admin.db.model.Publish;
import com.easyj.admin.db.model.PublishQO;
import com.easyj.admin.db.model.TaskComment;

/**
 * 会签示例
 * 将节点设为多实例，
 * 将任务执行设为用户组
 * 完成条件设为${nrOfInstances == nrOfCompletedInstances}，即所有人完成时才算完成
 * @author hjf
 *
 */
@Service
public class PublishServiceImpl implements PublishService{    
	
	@Autowired
	private  PublishMapper publishMapper;
	
	@Autowired
    private TaskRuntime taskRuntime;
	
	@Autowired
	private RuntimeService runtimeService;
	
	@Autowired
	private TaskService taskService;
	
	@Autowired
    private ProcessRuntime processRuntime;
	
	@Autowired
	private TaskCommentService taskCommentService;
	
	@Autowired
	private  HistoryService historyService;
	
	  	
	public Page<Publish> findPage(PublishQO filter){
	    Long total=publishMapper.countByExample(filter);
		List<Publish> rows=null;
		if(total>0l){
			filter.getPage().resetOffsetByTotal(total);
		    rows= publishMapper.selectByExample(filter);
		}
		
		Page<Publish> rtn=new Page<Publish>(rows,total,filter.getPage());
		return rtn;
	}


   	public List<Publish> findList(PublishQO filter){
        return publishMapper.selectByExample(filter);
    }
	public long count(PublishQO filter){
	     return publishMapper.countByExample(filter);
	}	


	public Publish findById(Long id){
		Publish entity= publishMapper.selectByPrimaryKey(id);
		return entity;
	}
	
	public List<TaskComment> findCommentsById(Long entityId){
		HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery();
		query.processInstanceBusinessKey(entityId.toString());
		query.processDefinitionKey(ProcessDefKey);
		HistoricProcessInstance processInstance =  query.singleResult();
		List<TaskComment> rtn=taskCommentService.findByProcInstId(processInstance.getId());
		return rtn;
	}
	
	
	@Transactional
	public int  apply(Publish entity) throws EasyjException{
		entity.setApplyTime(new Date());
		SimpleUser usr=SecurityUtil.getOperator();
		entity.setApplicantId(usr.getId());
		entity.setDeptId(usr.getDepartmentId());
		entity.setStatus(Level2ApplyStatusEnum.WAITING.getKey());	
		entity.setApplyTime(new Date());
		int rtn= publishMapper.insert(entity);
		
		//启动流程
		String businessKey = entity.getId().toString(); //业务key=entityId
		//流程参数
		HashMap<String, Object> varmap=new HashMap<String, Object>(5);
		varmap.put("applicant", SecurityUtil.getOperatorId().toString()); //指定任务申请人为登录用户
		varmap.put("pass", true); //是否通过先设为true,只要有一个不通过，就设为false(审批不通过)
	    processRuntime.start(ProcessPayloadBuilder
	                        .start()
	                        .withProcessDefinitionKey(ProcessDefKey)
	                        .withName(entity.getApplyName())
	                        .withVariables(varmap)
	                        .withBusinessKey(businessKey)
	                        .build());
		return rtn;
	}
	
	@Transactional
	public void approve(SimpleApproveVO approveVO) throws EasyjException{
		Task task=taskRuntime.task(approveVO.getTaskId());
		if(!task.getBusinessKey().equals(approveVO.getEntityId().toString())) {
			throw new  ValidateException("数据不符合要求！");
		}
		Publish entity=publishMapper.selectByPrimaryKey(approveVO.getEntityId());
		if(entity.getStatus().intValue()!=Level2ApplyStatusEnum.WAITING.getKey()){
			throw new  ValidateException("状态不是‘等待审批’");
		}					
		
		//加上审批意见
		ProcessUtils.addComment(task,SecurityUtil.getOperatorId().toString(), approveVO.isPassed(), approveVO.getComment());		
         //流程定义 指定了 assginee 不需要 claim
		
	    if(!approveVO.isPassed()) {//只要会签一个还通过，就不通过审批
		   taskService.setVariable(approveVO.getTaskId(), "pass", false);
	    }
	    
		taskService.complete(approveVO.getTaskId());
		
		
	}
	
	
	@Transactional(rollbackFor=Exception.class)
	public void auditApply(SimpleApproveVO approveVO) throws EasyjException{
		Task task=taskRuntime.task(approveVO.getTaskId());
		if(!task.getBusinessKey().equals(approveVO.getEntityId().toString())) {
			throw new  ValidateException("数据不符合要求！");
		}
		
		Publish entity=publishMapper.selectByPrimaryKey(approveVO.getEntityId());			
		//只加处理意见
		entity.setStatus(Level2ApplyStatusEnum.PASSED.getKey());
		entity.setAuditComment(approveVO.getComment());
		entity.setApproveId(approveVO.getApproveUserId());
		entity.setApproveTime(new Date());		
		publishMapper.updateByPrimaryKeySelective(entity);
		
		//加上审批意见
		ProcessUtils.addComment(task,SecurityUtil.getOperatorId().toString(), true, approveVO.getComment());		

		taskRuntime.claim(
               TaskPayloadBuilder.claim().withTaskId(approveVO.getTaskId()).build());
		taskRuntime.complete(
                TaskPayloadBuilder.complete()
                        .withTaskId(approveVO.getTaskId()) 
                        .build());  
				
	}
	
	
	@Transactional
	public int  updateEntity(Publish entity) throws EasyjException{
		
	    Publish find=publishMapper.selectByPrimaryKey(entity.getId());
		if(find.getApplicantId().longValue()!=SecurityUtil.getOperatorId().longValue()) {
			throw new  ValidateException("非法操作！");
		}
		if(find.getStatus()!=Level2ApplyStatusEnum.WAITING.getKey()) {
			throw new  ValidateException("非法操作,只能修改‘等待审批’的申请！");
		}
		entity.setStatus(find.getStatus());	
		int rtn= publishMapper.updateByPrimaryKey(entity);
		return rtn;
	}


	/**
     * 按实体ID取消流程
	 */
	@Transactional(rollbackFor=Exception.class)
	public int  cancel(Long id) throws EasyjException{
		Publish find=publishMapper.selectByPrimaryKey(id);
		if(find.getApplicantId().longValue()!=SecurityUtil.getOperatorId().longValue()) {
			throw new  ValidateException("非法操作！");
		}
		if(!(find.getStatus().intValue()==Level2ApplyStatusEnum.WAITING.getKey()
				||find.getStatus().intValue()==Level2ApplyStatusEnum.Repeat.getKey())){
			throw new  ValidateException("非法操作,状态不是‘等待审批’或‘"+Level2ApplyStatusEnum.Repeat.getText()+"’！");
		}
		
		find.setStatus(Level2ApplyStatusEnum.CANCEl.getKey());
		find.setApproveTime(new Date()); //共用
		
		int rtn= publishMapper.updateByPrimaryKey(find);
		
		
		//取消,delete流程实例 
		org.activiti.engine.runtime.ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(find.getId().toString(), ProcessDefKey).active().singleResult();
		runtimeService.deleteProcessInstance(processInstance.getId(), "申请人取消");
		
		return rtn;
	}



}
